<template>
  <a-modal
    v-bind="curOptions"
    v-model:open="curVisible"
    @cancel="curVisible = false"
    @ok="onModalOk"
  >
    <a-Form
      ref="form"
      :model="curFormData"
      :labelCol="{ span: 5 }"
      :wrapperCol="{ span: 18 }"
      :rules="curFormRuless"
    >
      <a-form-item key="slotType" name="slotType" label="插槽类型">
        <a-select
          v-model:value="curFormData.slotType"
          placeholder="请选择插槽类型"
          :options="curSlotTypeList"
          @change="onChangeSlotType"
        />
      </a-form-item>

      <template v-if="curFormData.slotType === BwSoltTypeEnum.convention">
        <a-form-item key="slotCode" name="slotCode" label="插槽标识">
          <a-input
            v-model:value="curFormData.cSlotCode"
            placeholder="请填写插槽标识"
          />
        </a-form-item>

        <a-form-item key="slotName" name="slotName" label="插槽名称">
          <a-input
            v-model:value="curFormData.cSlotName"
            placeholder="请填写插槽名称"
          />
        </a-form-item>

        <a-form-item label="插槽参数">
          <a-form-item-rest>
            <BwEmitParams
              ref="slotParam"
              :value="curFormData.cSlotParams"
              @add="onAddParam"
              @delete="onDelParam"
            />
          </a-form-item-rest>
        </a-form-item>
      </template>

      <template v-if="curFormData.slotType === BwSoltTypeEnum.trends">
        <a-form-item key="logicCode" name="logicCode" label="逻辑标识">
          <a-input
            v-model:value="curFormData.logicCode"
            placeholder="请填写逻辑标识"
          />
        </a-form-item>

        <a-form-item key="logicName" name="logicName" label="逻辑名称">
          <a-input
            v-model:value="curFormData.logicName"
            placeholder="请填写逻辑名称"
          />
        </a-form-item>

        <a-form-item
          key="trendVarFrom"
          name="trendVarFrom"
          label="动态变量来源"
        >
          <a-select
            placeholder="请选择动态变量来源"
            :options="curSlotVarFromTypeList"
            v-model:value="curFormData.trendVarFrom"
          />
        </a-form-item>

        <template v-if="curFormData.trendVarFrom == BwSlotVarFromEnum.comVar">
          <a-form-item key="comVarName" name="comVarName" label="组件变量名称">
            <a-input
              v-model:value="curFormData.comVarName"
              placeholder="请填写组件变量名称"
            />
          </a-form-item>
        </template>

        <template
          v-else-if="curFormData.trendVarFrom == BwSlotVarFromEnum.comProps"
        >
          <a-form-item
            key="comPorpName"
            name="comPorpName"
            label="组件外放属性"
          >
            <a-select
              v-model:value="curFormData.comPorpName"
              placeholder="请选择组件外放属性"
              :options="curCurtomComPropList"
            />
          </a-form-item>
        </template>

        <a-form-item label="插槽标识">
          <a-form-item-rest>
            <BwEmitLogic ref="logic" v-model:value="curFormData.tSlotCode" />
          </a-form-item-rest>
        </a-form-item>

        <a-form-item label="插槽参数">
          <a-form-item-rest>
            <BwEmitParams
              ref="slotParam"
              :value="curFormData.tSlotParams"
              @add="onAddParam"
              @delete="onDelParam"
            />
          </a-form-item-rest>
        </a-form-item>
      </template>
    </a-Form>
  </a-modal>
</template>

<script lang="ts" setup>
import { useComDesignStoreWithOut } from '@/store'
import { ref, unref, computed, watch, nextTick } from 'vue'

import {
  BwCustomComSoltTypeEnum as BwSoltTypeEnum,
  BwCustomComTrendSlotVarFromTypeEnum as BwSlotVarFromEnum,
} from '@bitwit/base-com-render'

import BwEmitParams from './param.vue'
import BwEmitLogic from './logic.vue'

interface BwComSlotInfoProps {
  visible: boolean
}

const designStore = useComDesignStoreWithOut()
const emit = defineEmits(['update:visible', 'ok'])
const props = withDefaults(defineProps<BwComSlotInfoProps>(), {
  visible: false,
})

const logic = ref()
const slotParam = ref()
const curFormData = ref<Record<string, any>>({})
const curVisible = computed({
  get: () => props.visible,
  set: (visible) => emit('update:visible', visible),
})

const curOptions = computed(() => {
  return {
    title: `新增外放插槽信息`,
    width: 800,
    okText: '确定',
    cancelText: '取消',
    destroyOnClose: true,
  }
})
const curSlotTypeList = computed(() => {
  return [
    { value: BwSoltTypeEnum.convention, label: '静态插槽' },
    { value: BwSoltTypeEnum.trends, label: '动态插槽' },
  ]
})

/** 插槽变量来源 */
const curSlotVarFromTypeList = computed(() => {
  return [
    { value: BwSlotVarFromEnum.comVar, label: '组件变量' },
    { value: BwSlotVarFromEnum.comProps, label: '外放属性' },
  ]
})

/** 当前自定义组件外放属性列表 */
const curCurtomComPropList = computed(() => {
  const list: Array<Record<string, string>> = []
  const designInfo = designStore.curDesignInfo
  const comProps = designInfo?.comProps

  if (Array.isArray(comProps) && comProps.length) {
    comProps.forEach((item) => {
      list.push({ label: item.name ?? '', value: item.key })
    })
  }
  return list
})

const curFormRuless = computed(() => {
  return {
    slotName: { required: true, message: `请填写插槽名称` },
    slotCode: { required: true, message: `请填写插槽标识` },
  }
})

const onAddParam = () => {
  const data = unref(curFormData)
  const slotType = data.slotType

  switch (slotType) {
    case BwSoltTypeEnum.convention: {
      const curParams = data.cSlotParams ?? []

      curParams.push({})
      curFormData.value.cSlotParams = curParams
      break
    }
    case BwSoltTypeEnum.trends: {
      const curParams = data.tSlotParams ?? []

      curParams.push({})
      curFormData.value.tSlotParams = curParams
      break
    }
    default: {
      break
    }
  }
}

const onDelParam = (index: number) => {
  const data = unref(curFormData)
  const slotType = data.slotType

  switch (slotType) {
    case BwSoltTypeEnum.convention: {
      const curParams = data.cSlotParams ?? []

      curParams.splice(index, 1)
      curFormData.value.cSlotParams = curParams
      break
    }
    case BwSoltTypeEnum.trends: {
      const curParams = data.tSlotParams ?? []

      curParams.splice(index, 1)
      curFormData.value.tSlotParams = curParams
      break
    }
    default: {
      break
    }
  }
}

const onModalOk = () => {
  const ele = unref(slotParam)
  const data = unref(curFormData)

  const slotType = data.slotType
  const curParams = ele.getParamList()

  let curCParams = unref(curFormData).cSlotParams
  let curTParams = unref(curFormData).tSlotParams
  switch (slotType) {
    case BwSoltTypeEnum.convention: {
      curCParams = curParams
      break
    }
    case BwSoltTypeEnum.trends: {
      curTParams = curParams
      break
    }
  }

  designStore
    .onAddSlot({
      slotType: unref(curFormData).slotType,
      conventionSlotInfo: {
        slotParams: curCParams,
        slotCode: unref(curFormData).cSlotCode,
        slotName: unref(curFormData).cSlotName,
      },
      trendsSlotInfo: {
        slotParams: curTParams,
        logicName: unref(curFormData).logicName,
        logicCode: unref(curFormData).logicCode,
        trendVarFrom: unref(curFormData).trendVarFrom,
        comVarName: unref(curFormData).comVarName,
        comPorpName: unref(curFormData).comPorpName,
        slotCode: unref(curFormData).tSlotCode,
      },
    })
    .then(() => (curVisible.value = false))
}

const onChangeSlotType = () => {
  nextTick(() => {
    const el = unref(logic)
    el && el.init()
  })
}
watch(
  () => curVisible.value,
  (newVal) => {
    if (newVal) {
      curFormData.value = {}
      nextTick(() => {
        const el = unref(logic)
        el && el.init()
      })
    }
  },
  { deep: true, immediate: true }
)
</script>

<style lang="less" scoped></style>
